#include "LeGraphicsView.h"
#include "LeGraphicsScene.h"
#include "LeGraphicsStyle.h"
#include "LeGraphicsRuler.h"
#include "LeGraphicsRulerBar.h"
#include "Solarized.h"

#include <QAction>
#include <QDebug>
#include <QElapsedTimer>
#include <QGraphicsItem>
#include <QGridLayout>
#include <QLineF>
#include <QOpenGLWidget>
#include <QScrollBar>
#include <QtMath>
#include <QVector>
#include <QWheelEvent>

//#define NO_MOUSE_EVENT

LeGraphicsView::LeGraphicsView(QWidget *parent):
    QGraphicsView(parent),
    m_profilingEnabled(false),
    m_orientation(XRightYUp),
    m_rotationAngle(0.0),
    m_scaleFactor(1.0),
    m_hRuler(new LeGraphicsRuler(this)),
    m_vRuler(new LeGraphicsRuler(this)),
    m_hRulerBar(new LeGraphicsRulerBar(LeGraphicsRulerBar::Horizontal)),
    m_vRulerBar(new LeGraphicsRulerBar(LeGraphicsRulerBar::Vertical))
{
    applyTransform();

    setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    // Because items don't move
    setOptimizationFlag(DontAdjustForAntialiasing, true);
    // Because it just work!
    //setOptimizationFlag(DontSavePainterState, true);
    // Still experimenting with this one
    // Need a gui settings for this and scene BSP depth for evaluation purpose
    //setViewportUpdateMode(FullViewportUpdate);
    setViewportUpdateMode(MinimalViewportUpdate);
    //setViewportUpdateMode(SmartViewportUpdate);
    //setViewportUpdateMode(BoundingRectViewportUpdate);

#ifdef NO_MOUSE_EVENT
    setInteractive(true);
#else
    setInteractionMode(MultipleSelectionMode);
#endif
    setupGrid();
}

LeGraphicsView::Orientation LeGraphicsView::orientation() const
{
    return m_orientation;
}

LeGraphicsView::InteractionMode LeGraphicsView::interactionMode() const
{
    return m_interactionMode;
}

qreal LeGraphicsView::rotation() const
{
    return m_rotationAngle;
}

qreal LeGraphicsView::pixelsPerSceneUnit() const
{
    return (mapFromScene(1, 1) - mapFromScene(0, 0)).x();
}

LeGraphicsScene *LeGraphicsView::graphicsScene() const
{
    return qobject_cast<LeGraphicsScene*>(scene());
}

void LeGraphicsView::setInteractionMode(LeGraphicsView::InteractionMode mode)
{
#ifdef NO_MOUSE_EVENT
#else
    m_mousePressScreenPos = QPoint();
    m_mousePressViewPoint = QPoint();
    m_mousePressScenePos = QPointF();
    m_lastMouseMoveScreenPos = QPoint();
    m_lastMouseMoveScenePos = QPointF();
    m_interactionMode = mode;
    m_dragStarted = false;
    m_mousePressed = false;
    if (scene() != nullptr)
        scene()->clearSelection();
    switch (m_interactionMode)
    {
        case ZoomMode:
            setInteractive(false);
            setDragMode(NoDrag);
            break;
        case MultipleSelectionMode:
            setInteractive(true);
            setDragMode(NoDrag);
            break;
        case SingleSelectionMode:
            setInteractive(true);
            setDragMode(NoDrag);
            break;
        case HandScrollMode:
            setInteractive(false);
            setDragMode(ScrollHandDrag);
            break;
    }

    updateViewportCursor(viewport());
#endif
}

void LeGraphicsView::enableProfiling(bool enabled)
{
    m_profilingEnabled = enabled;
    qDebug() << "Profiling is now " << (enabled ? "on" : "off");
}

void LeGraphicsView::setOrientation(LeGraphicsView::Orientation orientation)
{
    if (m_orientation == orientation)
        return;
    m_orientation = orientation;
    applyTransform();
    emit orientationChanged(m_orientation);
}

void LeGraphicsView::setRotation(qreal angle)
{
    if (qFuzzyCompare(m_rotationAngle, angle))
        return;
    m_rotationAngle = angle;
    applyTransform();
    emit rotationChanged(m_rotationAngle);
}

// TBD: reimplement QAbstractScrollArea::setupViewport
// TODO: emit aboutToReplaceViewport nad viewportReplaced()
void LeGraphicsView::enableOpenGL(bool enabled)
{
    if (enabled)
        setViewport(new QOpenGLWidget);
    else
        setViewport(new QWidget);
}

void LeGraphicsView::enableAntiAliasing(bool enabled)
{
    setRenderHint(QPainter::Antialiasing, enabled);
    setRenderHint(QPainter::TextAntialiasing, enabled);
}

void LeGraphicsView::zoomIn()
{
    zoomIn(1.15);
}

void LeGraphicsView::zoomOut()
{
    zoomOut(1.15);
}

// TODO: cursorPos is not the real point pointed to by the arrow of the cursor pixmap
// TODO: implment visibleSceneRect() to take into acccount scroll bar and co *if* needed
void LeGraphicsView::applyTransform()
{
    auto previousCursorViewPos = mapFromGlobal(QCursor::pos());
    auto previousCursorScenePos = mapToScene(previousCursorViewPos);
    if (!viewport()->geometry().contains(previousCursorViewPos))
        previousCursorScenePos = mapToScene(viewport()->geometry().center());

    resetTransform();
    scale(m_scaleFactor, m_scaleFactor);
    switch (m_orientation)
    {
        case XRightYUp: // Flip Y
            scale(1.0, -1.0);
            break;
        case XRightYDown: // No flip
            scale(1.0, 1.0);
            break;
        case XLeftYUp: // Flib both
            scale(-1.0, -1.0);
            break;
        case XLeftYDown: // Flip x
            scale(-1.0, 1.0);
            break;
    }
    rotate(m_rotationAngle);

    auto cursorViewPos = mapFromGlobal(QCursor::pos());
    auto cursorScenePos = mapToScene(cursorViewPos);
    if (!viewport()->geometry().contains(cursorViewPos))
        cursorScenePos = mapToScene(viewport()->geometry().center());
    auto cursorSceneOffset = cursorScenePos - previousCursorScenePos;
    const QRect viewRect(QPoint(0, 0), viewport()->size());
    const QRectF displayedSceneRect = mapToScene(viewRect).boundingRect();
    centerOn(displayedSceneRect.center() - cursorSceneOffset);
}

void LeGraphicsView::zoomIn(qreal factor)
{
    m_scaleFactor *= factor;
    applyTransform();
}

void LeGraphicsView::zoomOut(qreal factor)
{
    m_scaleFactor /= factor;
    applyTransform();
}

void LeGraphicsView::zoomAll()
{
    if (scene() == nullptr)
        return;
    fitInView(scene()->sceneRect(), Qt::KeepAspectRatio);
}

void LeGraphicsView::rotateLeft()
{
    rotateLeft(10.0);
}

void LeGraphicsView::rotateRight()
{
    rotateRight(10.0);
}

void LeGraphicsView::setVisibleSceneRect(QRectF rect)
{
    if (visibleSceneRect() == rect)
        return;
    fitInView(rect, Qt::KeepAspectRatio);
    updateRulers();
    emit visibleSceneRectChanged(visibleSceneRect());
}

void LeGraphicsView::setDrawGridInForeground(bool enabled)
{
    if (m_drawGridInForeground == enabled)
        return;
    m_drawGridInForeground = enabled;
    update();
    viewport()->update();
}

// FIXME: need to use the reminder of delta/360 (keeps sign)
void LeGraphicsView::rotateLeft(qreal delta)
{
    setRotation(std::fmod(m_rotationAngle + delta, 360.0));
}

void LeGraphicsView::rotateRight(qreal delta)
{
    setRotation(std::fmod(m_rotationAngle - delta, 360.0));
}

void LeGraphicsView::wheelEvent(QWheelEvent *event)
{
    if (event->modifiers().testFlag(Qt::ControlModifier))
    {
        auto angle = event->angleDelta().y();
        auto factor = qPow(1.0015, angle);
        m_scaleFactor *= factor;
        applyTransform();
        event->accept();
    }
    else if (event->modifiers().testFlag(Qt::ShiftModifier))
    {
        if (event->delta() > 0)
            rotateLeft();
        else
            rotateRight();
        event->accept();
    }
    else
        QGraphicsView::wheelEvent(event);
    updateRulers();
}

static QString ViewportUpdateModeToString(QGraphicsView::ViewportUpdateMode mode)
{
    switch (mode) {
        case QGraphicsView::FullViewportUpdate:
            return "Full";
        case QGraphicsView::MinimalViewportUpdate:
            return "Min.";
        case QGraphicsView::SmartViewportUpdate:
            return "Smart";
        case QGraphicsView::NoViewportUpdate:
            return "None";
        case QGraphicsView::BoundingRectViewportUpdate:
            return "BRect";
        default:
            return "?";
    }
}

// Needed b/c fitInView, etc... are not under our control
void LeGraphicsView::paintEvent(QPaintEvent *event)
{
    QElapsedTimer timer;
    timer.start();
    auto tx = transform().rotate(-m_rotationAngle);
    m_scaleFactor = qMax(qAbs(tx.m11()), qAbs(tx.m22()));
    QGraphicsView::paintEvent(event);
    qreal elapsed = timer.elapsed();

    if (m_profilingEnabled)
    {
        qDebug() << "QGV:PE" << QString("%1 px = %2 %3").arg(pixelsPerSceneUnit()).arg(graphicsScene()->unitScaleFactor()).arg(graphicsScene()->unitOfMeasure())
                 << QString("OpenGL: %1").arg(qobject_cast<QOpenGLWidget*>(viewport()) ? "true" : "false")
                 << QString("Viewport mode: %1").arg(ViewportUpdateModeToString(viewportUpdateMode()))
                 << QString("Event rect: %1, %2 %3x%4").arg(event->rect().x()).arg(event->rect().y()).arg(event->rect().width()).arg(event->rect().height())
                 << QString("Visible items: %1").arg(scene()->items(mapToScene(event->rect()).boundingRect(), Qt::IntersectsItemBoundingRect).count())
                 << QString("Painted in %1 ms").arg(elapsed);
    }
}

void LeGraphicsView::updateViewportCursor(QWidget *viewport)
{
    switch (m_interactionMode)
    {
        case ZoomMode:
            viewport->setCursor(Qt::ArrowCursor);
            break;
        case SingleSelectionMode:
            viewport->setCursor(Qt::ArrowCursor);
            break;
        case MultipleSelectionMode:
            viewport->setCursor(Qt::ArrowCursor);
            break;
        case HandScrollMode:
            break;
    }
}

void LeGraphicsView::setupViewport(QWidget *viewport)
{
    QGraphicsView::setupViewport(viewport);
    updateViewportCursor(viewport);
}

void LeGraphicsView::mousePressEvent(QMouseEvent *event)
{
#ifdef NO_MOUSE_EVENT
    QGraphicsView::mousePressEvent(event);
    return;
#else
    m_mousePressViewPoint = event->pos();
    m_mousePressScreenPos = event->globalPos();
    m_mousePressScenePos = mapToScene(m_mousePressViewPoint);
    m_lastMouseMoveScenePos = m_mousePressScenePos;
    m_lastMouseMoveScreenPos = m_mousePressScreenPos;
    m_mousePressed = true;
    m_dragStarted = false;

    switch (m_interactionMode)
    {
        case SingleSelectionMode:
            QGraphicsView::mousePressEvent(event);
            return;
        case MultipleSelectionMode:
            QGraphicsView::mousePressEvent(event);
            return;
        case HandScrollMode:
            QGraphicsView::mousePressEvent(event);
            return;
        case ZoomMode:
            event->accept();
            return;
    }
#endif
}

void LeGraphicsView::mouseDoubleClickEvent(QMouseEvent *event)
{
#ifdef NO_MOUSE_EVENT
    QGraphicsView::mouseDoubleClickEvent(event);
    return;
#else
    switch (m_interactionMode)
    {
        case HandScrollMode:
            QGraphicsView::mouseDoubleClickEvent(event);
            break;

        case SingleSelectionMode:
            QGraphicsView::mousePressEvent(event);
            return;

        case MultipleSelectionMode:
            if (!m_dragStarted)
            {
                QGraphicsView::mouseDoubleClickEvent(event);
                break;
            }
            event->accept();
            break;

        case ZoomMode:
            event->accept();
            break;
    }
#endif
}

void LeGraphicsView::mouseReleaseEvent(QMouseEvent *event)
{
#ifdef NO_MOUSE_EVENT
    QGraphicsView::mouseReleaseEvent(event);
    return;
#else
    switch (m_interactionMode)
    {
        case HandScrollMode:
            QGraphicsView::mouseReleaseEvent(event);
            break;

        case SingleSelectionMode:
            QGraphicsView::mouseReleaseEvent(event);
            break;

        case MultipleSelectionMode:
        {
            if (!m_dragStarted)
            {
                QGraphicsView::mouseReleaseEvent(event);
                break;
            }
            event->accept();
            const QRect rect(viewport()->mapFromGlobal(m_mousePressScreenPos),
                             viewport()->mapFromGlobal(m_lastMouseMoveScreenPos));
            viewport()->update(rect.normalized().adjusted(-1, -1, 1, 1));
            if (scene() != nullptr)
            {
                QPainterPath path;
                path.addRect(QRectF(m_mousePressScenePos, m_lastMouseMoveScenePos).normalized());
                scene()->setSelectionArea(path, Qt::ReplaceSelection);
            }
            break;
        }
        case ZoomMode:
        {
            event->accept();
            const QRect viewportBox(viewport()->mapFromGlobal(m_mousePressScreenPos),
                             viewport()->mapFromGlobal(m_lastMouseMoveScreenPos));
            viewport()->update(viewportBox.normalized().adjusted(-1, -1, 1, 1));
            if (viewportBox.height() > 0) // top to bottom movement
                fitInView(QRectF(m_mousePressScenePos, m_lastMouseMoveScenePos).normalized(),
                          Qt::KeepAspectRatio);
            else
            {
                QRectF outer(viewport()->parentWidget()->mapToGlobal(viewport()->geometry().topLeft()),
                             viewport()->parentWidget()->mapToGlobal(viewport()->geometry().bottomRight()));
                QRectF inner = QRectF(m_mousePressScreenPos, m_lastMouseMoveScreenPos).normalized();
                qreal scaleFactor = qMin(outer.width()*1.0/inner.width(),
                                         outer.height()*1.0/inner.height());
                zoomOut(scaleFactor);
                centerOn(mapToScene(mapFromGlobal(inner.center().toPoint())));
            }

            break;
        }
    }
    m_mousePressed = false;
    m_dragStarted = false;
#endif
}

void LeGraphicsView::mouseMoveEvent(QMouseEvent *event)
{
#ifdef NO_MOUSE_EVENT
    QGraphicsView::mouseMoveEvent(event);
    return;
#else
    const QRect oldViewportRect(viewport()->mapFromGlobal(m_mousePressScreenPos),
                                viewport()->mapFromGlobal(m_lastMouseMoveScreenPos));

    const QPoint mousePressPos = viewport()->mapFromGlobal(m_mousePressScreenPos);
    m_lastMouseMoveScreenPos = event->globalPos();
    m_lastMouseMoveScenePos = mapToScene(event->pos());

    const QRect newViewportRect(viewport()->mapFromGlobal(m_mousePressScreenPos),
                                viewport()->mapFromGlobal(m_lastMouseMoveScreenPos));

    if (m_mousePressed && !m_dragStarted && itemAt(mousePressPos) == nullptr)
        m_dragStarted = QLineF(m_mousePressScreenPos, m_lastMouseMoveScreenPos).length() > 1;

    switch (m_interactionMode)
    {
        case HandScrollMode:
            QGraphicsView::mouseMoveEvent(event);
            break;

        case SingleSelectionMode:
            QGraphicsView::mouseMoveEvent(event);
            break;

        case MultipleSelectionMode:
            if (!m_dragStarted)
            {
                QGraphicsView::mouseMoveEvent(event);
            }
            else
            {
                event->accept();
            }
            break;

        case ZoomMode:
            event->accept();
            break;
    }

    if (m_dragStarted)
    {
        // FIXME: we should rely on style to get the rect adjustement
        viewport()->update(oldViewportRect.normalized().adjusted(-2, -2, 2, 2));
        viewport()->update(newViewportRect.normalized().adjusted(-2, -2, 2, 2));
    }

    m_hRulerBar->setCursorPosition(m_lastMouseMoveScenePos);
    m_vRulerBar->setCursorPosition(m_lastMouseMoveScenePos);

    // FIXME: we should rely on style to get the rect adjustement
    //viewport()->update(QRect(-50, -50, 100, 100).translated(viewport()->mapFromGlobal(oldMouseScreenPos)));
#endif
}

void LeGraphicsView::drawBackground(QPainter *painter, const QRectF &rect)
{
    QGraphicsView::drawBackground(painter, rect);

    if (graphicsScene() == nullptr)
        return;

    if (m_drawGridInForeground)
        return;

    drawGrid(painter, rect);
}

// FIXME: GraphicsPalette should be managed by GraphicsView, not scene
void LeGraphicsView::drawForeground(QPainter *painter, const QRectF &rect)
{
    QGraphicsView::drawForeground(painter, rect);

    if (graphicsScene() == nullptr)
        return;

    if (!m_drawGridInForeground)
        return;

    drawGrid(painter, rect);
}

void LeGraphicsView::updateRulers()
{
    const QRect viewRect(QPoint(0, 0), viewport()->size());
    const QRectF displayedSceneRect = mapToScene(viewRect).boundingRect();
    switch (m_orientation) {
        case XRightYDown:
            m_hRuler->setMinimumValue(displayedSceneRect.left());
            m_hRuler->setMaximumValue(displayedSceneRect.right());
            m_vRuler->setMinimumValue(displayedSceneRect.top());
            m_vRuler->setMaximumValue(displayedSceneRect.bottom());
            break;
        case XRightYUp:
            m_hRuler->setMinimumValue(displayedSceneRect.left());
            m_hRuler->setMaximumValue(displayedSceneRect.right());
            m_vRuler->setMinimumValue(displayedSceneRect.bottom());
            m_vRuler->setMaximumValue(displayedSceneRect.top());
            break;
        case XLeftYDown:
            m_hRuler->setMinimumValue(displayedSceneRect.right());
            m_hRuler->setMaximumValue(displayedSceneRect.left());
            m_vRuler->setMinimumValue(displayedSceneRect.top());
            m_vRuler->setMaximumValue(displayedSceneRect.bottom());
            break;
        case XLeftYUp:
            m_hRuler->setMinimumValue(displayedSceneRect.right());
            m_hRuler->setMaximumValue(displayedSceneRect.left());
            m_vRuler->setMinimumValue(displayedSceneRect.bottom());
            m_vRuler->setMaximumValue(displayedSceneRect.top());
            break;
        default:
            break;
    }
    m_hRuler->setSize(viewRect.width());
    m_vRuler->setSize(viewRect.height());
}

void LeGraphicsView::resizeEvent(QResizeEvent *event)
{
    QGraphicsView::resizeEvent(event);
    updateRulers();
}

void LeGraphicsView::setupGrid()
{
    m_hRuler->setCoarseMultiplier(10);
    m_hRuler->setMinimumTickSpacing(10);
    m_hRuler->setMinimumValueStep(0.001);

    m_vRuler->setCoarseMultiplier(10);
    m_vRuler->setMinimumTickSpacing(10);
    m_vRuler->setMinimumValueStep(0.001);

    QGridLayout *layout = new QGridLayout;
    layout->setSpacing(0);
    layout->setMargin(0);
    auto m_topLeftWidget = new QWidget();
    m_topLeftWidget->setFixedSize(LeGraphicsRulerBar::BREADTH, LeGraphicsRulerBar::BREADTH);
    m_topLeftWidget->setStyleSheet(QString("background-color:%1;").arg(
                                      Solarized::backgroundHighlight.name()));
    //m_topLeftWidget->hide();
    m_hRulerBar->setRuler(m_hRuler);
    m_hRulerBar->setFixedHeight(LeGraphicsRulerBar::BREADTH);
    m_hRulerBar->setBackgroundColor(Solarized::backgroundHighlight);
    m_hRulerBar->setForegroundColor(Solarized::emphasisedContent);
    //m_hRulerBar->hide();
    auto m_topRightWidget = new QWidget();
    m_topRightWidget->setFixedSize(0, LeGraphicsRulerBar::BREADTH);
    //m_topRightWidget->hide();
    m_vRulerBar->setRuler(m_vRuler);
    m_vRulerBar->setFixedWidth(LeGraphicsRulerBar::BREADTH);
    m_vRulerBar->setBackgroundColor(Solarized::backgroundHighlight);
    m_vRulerBar->setForegroundColor(Solarized::emphasisedContent);
    //m_vRulerBar->hide();
    auto m_bottomLeftWidget = new QWidget();
    m_bottomLeftWidget->setFixedSize(LeGraphicsRulerBar::BREADTH, 0);
    //m_bottomLeftWidget->hide();
    horizontalScrollBar()->installEventFilter(this);
    verticalScrollBar()->installEventFilter(this);
    layout->addWidget(m_topLeftWidget, 0, 0);
    layout->addWidget(m_hRulerBar, 0, 1);
    layout->addWidget(m_topRightWidget, 0, 2);
    layout->addWidget(m_vRulerBar, 1, 0);
    layout->addWidget(m_bottomLeftWidget, 2, 0);
    layout->addWidget(viewport(), 1, 1);
    setLayout(layout);
    setViewportMargins(LeGraphicsRulerBar::BREADTH, LeGraphicsRulerBar::BREADTH, 0, 0);
}

void LeGraphicsView::drawGrid(QPainter *painter, const QRectF &rect)
{
    auto style = graphicsScene()->graphicsStyle();
    GraphicsStyleOption option;
    option.exposedRect = rect;
    option.state = LeGraphicsStyle::NoStateFlag;
    option.palette = graphicsScene()->graphicsPalette();

    QRectF sceneBox(m_mousePressScenePos, m_lastMouseMoveScenePos);
    switch (m_interactionMode)
    {
        case ZoomMode:
            if (!m_dragStarted)
                break;
            if (sceneBox.height() > 0)
                style->drawZoomInBox(&option, painter, sceneBox.normalized());
            else
                style->drawZoomOutBox(&option, painter, sceneBox.normalized());
            break;
        case MultipleSelectionMode:
            if (!m_dragStarted)
                break;
            style->drawRubberBand(&option, painter,
                                  QRectF(m_mousePressScenePos,
                                         m_lastMouseMoveScenePos).normalized());
            break;
        default:
            break;
    }

    style->drawMajorGrid(&option, painter,
                         m_hRuler->majorValues(), m_vRuler->majorValues(),
                         QPointF(m_hRuler->minimumValue(), m_vRuler->minimumValue()),
                         QPointF(m_hRuler->maximumValue(), m_vRuler->maximumValue()));

    style->drawMinorGrid(&option, painter,
                         m_hRuler->minorValues(), m_vRuler->minorValues(),
                         QPointF(m_hRuler->minimumValue(), m_vRuler->minimumValue()),
                         QPointF(m_hRuler->maximumValue(), m_vRuler->maximumValue()));

    style->drawOrigin(&option, painter, QPointF());
//    style->drawCursor(&option, painter,
    //                      m_lastMouseMoveScenePos);
}

void LeGraphicsView::updateSelection()
{
    if (m_interactionMode == SingleSelectionMode && m_scene->selectedItems().count() > 1)
        m_scene->selectedItems().last()->setSelected(false);
}

QRectF LeGraphicsView::visibleSceneRect() const
{
    const QRectF result = mapToScene(QRect(QPoint(0, 0), viewport()->size())).boundingRect();
    return result;
}

void LeGraphicsView::setLeGraphicsScene(LeGraphicsScene *scene)
{
    if (m_scene != nullptr)
        m_scene->disconnect(this);
    m_scene = scene;
    if (m_scene != nullptr)
    {
        setScene(m_scene);
        updateSelection();
        connect(m_scene, &LeGraphicsScene::selectionChanged,
                this, &LeGraphicsView::updateSelection);
    }
}

#include <QDebug>
#include <QKeyEvent>
#include <QFocusEvent>
#define DEBUG() qDebug() << __PRETTY_FUNCTION__

void LeGraphicsView::keyPressEvent(QKeyEvent *event)
{
    DEBUG() << event->key();
    QGraphicsView::keyPressEvent(event);
}

void LeGraphicsView::keyReleaseEvent(QKeyEvent *event)
{
    DEBUG() << event->key();
    QGraphicsView::keyReleaseEvent(event);
}

void LeGraphicsView::focusInEvent(QFocusEvent *event)
{
    DEBUG();
    QGraphicsView::focusInEvent(event);
}

void LeGraphicsView::focusOutEvent(QFocusEvent *event)
{
    DEBUG();
    QGraphicsView::focusOutEvent(event);
}

void LeGraphicsView::enterEvent(QEvent *event)
{
    DEBUG();
    QGraphicsView::enterEvent(event);
}

void LeGraphicsView::leaveEvent(QEvent *event)
{
    DEBUG();
    QGraphicsView::leaveEvent(event);
}
